require "kuru_wrap.lua"
require "broken.lua"
require "lib/FloatingCoordinate.lua"
guideElapsedTime = 0
GUIDE_DELAY_TIME = 3000
g_sound = nil
g_sound2 = nil
offset=0.25
closeValue=0.08
kuruHumanAction=nil
mirrorNode=nil
isClosing=false
isCanClose=true
g_speed = 0.5 --缩放速度
g_nodes=nil
preOri = nil
firstSetting = false
M_PI = 3.14159265358979
_preAspectType = CameraConfigAspectRatio.ANY
firstSetting = false
_brokenNode = nil
_scratchNode = nil
_shakeNode = nil
_shakingNode=nil
isShaking=true
g_time=0
originFrames = {}
totalElapsedTime = 0
triggerTime = 0
triggerIndex = -1
count =0
isSlowTriggered = false --能不能捕捉图像
crownConfig={
    {
        {type=6,id=210,intensity=0.6},  
        {type=10},    
        {path='basicDistortion.json',type=7},
        {path='303739_2_plain/b_sg',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=20,blendmode=BlendMode.None},
        {path='303739_2_plain/f_hg',type=1,scale=1.4,tx=0,ty=-1.23,anchor=KaleStickerNodeAnchorType.CENTER,location=KaleStickerNodeLocationType.FACE,flip=false,fps=20,blendmode=BlendMode.Normal},
        {path='303739_2_plain/f_heart.png',type=1,scale=0.41,tx=0.49,ty=0.58,anchor=KaleStickerNodeAnchorType.CENTER,location=KaleStickerNodeLocationType.EYE_LB,flip=false,fps=20,blendmode=BlendMode.Normal},
        {path='303739_2_plain/b_gg',type=5,scale=0.4,x=0.8,y=-0.8,width=1.3,height=0.9,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=10,blendmode=BlendMode.None},
        {path='303739_2_plain/b_x',type=0,scale=0.17,tx=-0.06,ty=-0.08,anchor=KuruBackgroundImageNodeAnchorType.LEFT_TOP,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=20,blendmode=BlendMode.None},
        {path='303739_2_plain/b_xx',type=0,scale=0.17,tx=0.06,ty=0.08,anchor=KuruBackgroundImageNodeAnchorType.RIGHT_BOTTOM,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=20,blendmode=BlendMode.None},
        {path='303739_2_plain/b_up.png',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.TOP,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=20,blendmode=BlendMode.None},
        {path='303739_2_plain/b_down.png',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.BOTTOM,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=20,blendmode=BlendMode.None},
        {path='303739_2_plain/b_pink.png',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,flip=false,fps=20,blendmode=BlendMode.None},
        
      },
}

function initialize(scene)
 local kuruEngineInstance = KuruEngine.getInstance()
 kuruFaceDetector = KuruFaceDetectorExtension.cast(kuruEngineInstance:getExtension('KuruFaceDetector'))

 scene:getInternalScene():setHandDetection(true)
 kuruHumanAction = KuruHumanActionExtension.cast(kuruEngineInstance:getExtension("KuruHumanAction"))

--  EngineStatus.instance():setBoolean("useBuiltInDistortionInScript", true)

 flImage = FloatingCoordinate:new(720, 1280)

 soundExtension = KuruSoundExtension.cast(KuruEngine.getInstance():getExtension("KuruSound"))
 g_sound = soundExtension:loadEx(BASE_DIRECTORY .. "cn_crowntwo.mp3")
 g_sound2 = soundExtension:loadEx(BASE_DIRECTORY .. "cn_crownone.mp3")
 playSoundWithIndex(1)
   
   distortionNode = KaleFaceDistortionNode.createWithPath(BASE_DIRECTORY .. "basicDistortion.json")
   distortionNode=addNodeAndRelease(scene, distortionNode)
  
  _shakingNode=addNodeAndRelease(scene, KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "shaking.frag", true))
  _shakingNode:getMaterial():getParameter("time"):setFloat(g_time)
  _shakingNode:setEnabled(false)
  
  mirrorNode = addNodeAndRelease(scene, getFragmentShader("mirror.frag"))
  mirrorNode:getMaterial():getParameter("moveOffset"):setFloat(offset)
  originSnap = getSnapshot(scene)
 
  getCrownNode(scene,crownConfig,nil)
 
  originSnap2 = getSnapshot(scene)

 

  local frameMesh = Mesh.createQuadFullscreen()
  drawModel = Model.create(frameMesh)
  frameMesh:release()

  material = Material.createWithShaderFile("res/shaders/passthrough.vert", "res/shaders/passthrough.frag", Nil)
  material:getParameter("u_worldViewProjectionMatrix"):setMatrix(Matrix.identity())
  material:getParameter("u_texture"):setSampler(originSnap2:getSnapshot())
  drawModel:setMaterial(material, -1)

  fragNode = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "texture.frag", true) --从当前屏幕显示或者从buffer[]显示
  fragNode:setChannel1(originSnap:getSnapshot())
  scene:addNodeAndRelease(fragNode)
  local config = KuruEngine.getInstance():getCameraConfig()
   
  g_guideNode = flImage:getAlignImageNode("303739_2_plain/hand_trigger.png", 500, 340, config:getAspectRatio(), BlendMode.Normal, FloatingAlign.CENTER)
  if isExposed == nil then
    scene:addNodeAndRelease(g_guideNode)
  end

end
function frameReady(scene, elapsedTime)
    
    if g_guideNode:isEnabled() then
        if SceneRenderConfig.instance():isRenderModeVideo() then
          g_guideNode:setEnabled(false)
          isExposed = "true"
        end
    end
      guideElapsedTime = guideElapsedTime + elapsedTime
      if guideElapsedTime >= GUIDE_DELAY_TIME then
        if g_guideNode:isEnabled() then
          g_guideNode:setEnabled(false)
          isExposed = "true"
        end
        guideElapsedTime = 0
      end

    local config = KuruEngine.getInstance():getCameraConfig()
    local didFrameChanged = isChangedFrame(scene)
    if isCanClose==false and isClosing==false then
         KuruWrap.frameReardy()
         if (didFrameChanged == true or firstSetting == false) then	
             setEffects(scene)
             broken_wrap.setBroken(_brokenNode,_preAspectType,1, 0, 1, -17, 0, 17, 1)
             broken_wrap.setScratch(scene,_scratchNode)
             broken_wrap.setShake(_shakeNode) 	
             firstSetting = true
         else
             broken_wrap.setScratch(scene,_scratchNode)
             broken_wrap.setShake(_shakeNode) 	
         end
         if(preOri ~= config.deviceOrientation) then
             setEffects(scene)
             broken_wrap.setBroken(_brokenNode,_preAspectType,1, 0, 1, -17, 0, 17, 1)
         end
         preOri = config.deviceOrientation
    end
    
    if(isClosing) then
        offset = offset - g_speed * elapsedTime * 0.001
        if(offset < closeValue)then
            if(isShaking) then
              mirrorNode:setEnabled(false)
              g_time=g_time+0.1
              print("KURUsdfsdfsdfsdfsdfsdfsdf"..g_time)
              _shakingNode:setEnabled(true)
              _shakingNode:getMaterial():getParameter("time"):setFloat(g_time)
              -- print("KURUsdfs11111111111111111sdf"..g_time)
              
              if(g_time>2.5)then
                _shakingNode:setEnabled(false)
                isShaking=false
                g_time=0
                -- print("KURUsdfs11111111111111111sdf")
              end
            else
              isClosing = false
              resetValue()
              distortionNode:setEnabled(false)

              KuruWrap.showGroupNodes(g_nodes,1)
              KuruWrap.frameReardy()
              KuruWrap.playAni()
            end
            
        end
    end
    mirrorNode:getMaterial():getParameter("moveOffset"):setFloat(offset)
    handCount = kuruHumanAction:getHandCount() --获得手指数量
    if (handCount > 0) then
        for i = 0, handCount - 1 do
         
          local hand = kuruHumanAction:getHandData(i) --手数据
          local action = hand:getHandAction() --手的行为
          if(isCanClose) then
            if hand:isPistol() then
                isClosing = true
                isCanClose = false 
                playSoundWithIndex(2) 
              --  resetValue() 
            end
          end
         
        end
    else
    end
    totalElapsedTime = totalElapsedTime + elapsedTime
    totalIndex = math.floor(totalElapsedTime/50)
    if totalIndex < 20 then
        if(isClosing==false and isCanClose==false) then
            fragNode:setChannel1(originSnap2:getSnapshot())
        end
        return
    end
    if totalIndex > 118 then
        if isClosing==false and isCanClose==false then
          distortionNode:setEnabled(true)

         KuruWrap.showGroupNodes(g_nodes,0)
         _brokenNode:setEnabled(false)
         _scratchNode:setEnabled(false)
         _shakeNode:setEnabled(false) 
        end
    end
    if totalIndex >=119 then
       
        if isClosing==false and isCanClose==false then
            isCanClose=true
            firstSetting = false
             --恢复原始状态
             isShaking=true
             mirrorNode:setEnabled(true) 
             offset=0.25
             playSoundWithIndex(1) 
        end
       
    end
   local index = math.floor(triggerTime/70) --每隔70ms取一次图片，index为0，1，2
   if triggerIndex ~= index then
     if isSlowTriggered then
       triggerSlowmotion(index, scene)
     end
    triggerIndex = index
   end
  triggerTime = triggerTime + elapsedTime

end
function triggerSlowmotion(frameIndex, scene)
    print("triggerSlowmotion")
    local index = frameIndex % 3
    -- save frame
    if frameIndex < 50 then --总共50帧
      state = FrameBufferBindingState.create()
      local frameBuffer = FrameBuffer.create("STORED_FB_1", math.floor(scene:getResolution().x/2), math.floor(scene:getResolution().y/2), TextureFormat.RGBA)
      frameBuffer:bindWithViewport(true)
      drawModel:draw()
      state:restore()
      originFrames[#originFrames + 1] = frameBuffer
    end
    if count > 20 then --消除慢速效果
      -- all slow time = 0.08 x 60 x 3
      fragNode:setChannel1(originSnap:getSnapshot())
      isSlowTriggered = false
      clearBuffers()
      count = 0
      return
    end
  
  
    if index == 0 then --index为3的倍数，每隔3帧取一次
      -- show slow
      local slowFrameBuffer = getFrameBuffer() --取到第一帧
      if (slowFrameBuffer == nil) then --播放结束
        fragNode:setChannel1(originSnap:getSnapshot())
        isSlowTriggered = false
        clearBuffers()
        count = 0
        return
      else
        local frameSampler = TextureSampler.createWithTexture(slowFrameBuffer:getRenderTarget(0):getTexture())
  
        removeHeadBuffer() --移除第一个buffer
  
        if frameSampler ~= nil then
          fragNode:setChannel1(frameSampler)
          frameSampler:release()
          count = count + 1
        end
      end
    end
end
function resetValue()
    triggerTime = 0
    triggerIndex = -1
    totalElapsedTime = 0
    isSlowTriggered = true
end
function getFrameBuffer()
    for i = 1, #originFrames do
      if originFrames[i] ~= nil then
        return originFrames[i]
      end
    end
    return nil
end
function removeHeadBuffer()
    for i = 1, #originFrames do
      if originFrames[i] ~= nil then
        originFrames[i]:release()
        originFrames[i] = nil
        return
      end
    end
  end
  
function clearBuffers()
    for i = 1, #originFrames do
      if originFrames[i] ~= nil then
        originFrames[i]:release()
        originFrames[i] = nil
      end
    end
end
function isChangedFrame(scene)
    local aspectRatio = CameraConfig.instance():getAspectRatio()
	local result = false
    if _preAspectType ~= aspectRatio then
      result = true
    end
	_preAspectType = aspectRatio
    return result
end

function setEffects(scene)
	if(_brokenNode ~= nil) then
		scene:removeNode(_brokenNode)
	end
	if(_scratchNode ~= nil) then
		scene:removeNode(_scratchNode)
	end
	if(_shakeNode ~= nil) then
		scene:removeNode(_shakeNode)
  end

  	_brokenNode = addNodeAndRelease(scene, KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "broken.frag", true))
  	_scratchNode = addNodeAndRelease(scene, KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "scratch.frag", true))
    _shakeNode = addNodeAndRelease(scene, KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "shake.frag", true))
    
end
function getFragmentShader(filePath)
    return KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. filePath, true)
end

function getCrownNode(scene,config,snap)
    g_nodes=KuruWrap.addGroupNodesWithConfig(scene,config,snap)
   -- KuruWrap.showGroupNodes(g_nodes,1)
    return g_nodes
end
function getSnapshot(scene)
    local node = KuruSnapshotNode.create()
    node:setFrameBufferScale(0.5, 0.5)
    scene:addNodeAndRelease(node)
    return node
end
function addNodeAndRelease(scene, node)
    scene:addNode(node)
    node:release()
    return node
end
function onAspectRatioChanged(scene)
  local config = KuruEngine.getInstance():getCameraConfig()
  aspectRatio = config:getAspectRatio()
  flImage:getAlignImageNode(g_guideNode, 500, 340, aspectRatio, BlendMode.Normal, FloatingAlign.CENTER)
end
function playSoundWithIndex(index)

  -- if(g_sound)then
  --   g_sound:stop()
  -- end
  if(g_sound2)then
    g_sound2:stop()
  end
  if(index==1)then
  
    g_sound:play()
  else
    g_sound:stop()
    g_sound2:play(false)
  end
end
